# -*- coding: utf-8 -*-
"""
HaaS506 RTU 网络模块
简化版本 - 网络连接和管理
"""

import network
import utime
from modem import net
import rtu_config

# 网络状态
_network_connected = False
_network_client = None
_retry_count = 0
_last_connected_time = 0
_connection_lost_time = 0
_recovery_callbacks = []


def init():
    """初始化网络模块"""
    print("[NETWORK] Network module initialized")
    return True


def on_4g_cb(args):
    """4G连接回调"""
    global _network_connected, _last_connected_time, _connection_lost_time
    pdp = args[0]
    netwk_sta = args[1]

    if netwk_sta == 1:
        # 网络连接成功
        was_disconnected = not _network_connected
        _network_connected = True
        rtu_config.g_network_ready = True
        _last_connected_time = utime.time()

        if was_disconnected and _connection_lost_time > 0:
            # 网络恢复
            current_time = utime.time()
            disconnect_duration = current_time - _connection_lost_time

            # 防止时间异常导致负数（如系统重启或时间未同步）
            if disconnect_duration < 0:
                print("[NETWORK] 4G reconnected (time sync issue detected)")
                disconnect_duration = 0
            else:
                print(
                    "[NETWORK] 4G reconnected after {:.1f} seconds".format(
                        disconnect_duration
                    )
                )

            _connection_lost_time = 0
            _retry_count = 0

            # 触发恢复回调
            _trigger_recovery_callbacks()
        else:
            print("[NETWORK] 4G connected")
    else:
        # 网络断开
        if _network_connected:
            _connection_lost_time = utime.time()
            print("[NETWORK] 4G disconnected, starting recovery...")

        _network_connected = False
        rtu_config.g_network_ready = False
        rtu_config.g_mqtt_connected = False


def connect_network():
    """连接网络"""
    global _network_connected, _network_client, _retry_count

    try:
        print("[NETWORK] Connecting to network...")

        _network_client = network.NetWorkClient()
        g_register_network = False

        if (
            _network_client._stagecode is not None
            and _network_client._stagecode == 3
            and _network_client._subcode == 1
        ):
            g_register_network = True
        else:
            print(
                "[NETWORK] Network register failed, code: {}, {}".format(
                    _network_client._stagecode, _network_client._subcode
                )
            )
            g_register_network = False

        if g_register_network:
            _network_client.on(1, on_4g_cb)
            _network_client.connect(None)
        else:
            _retry_count += 1
            print("[NETWORK] Network register failed {} times".format(_retry_count))
            return False

        # 等待连接成功
        timeout = 10  # 10秒超时
        start_time = utime.time()
        while utime.time() - start_time < timeout:
            if _network_connected:
                print("[NETWORK] Network register succeeded")
                _retry_count = 0
                return True
            utime.sleep(0.1)

        print("[NETWORK] Network connect timeout")
        _retry_count += 1
        return False

    except Exception as e:
        print("[NETWORK] Connect network error: {}".format(e))
        return False


def disconnect_network():
    """断开网络"""
    global _network_connected, _network_client

    try:
        if _network_client and _network_connected:
            _network_client.disconnect()
            _network_connected = False
            rtu_config.g_network_ready = False
            print("[NETWORK] Network disconnected")
        return True
    except Exception as e:
        print("[NETWORK] Disconnect network error: {}".format(e))
        return False


def is_connected():
    """检查网络连接状态"""
    return _network_connected


def get_signal_strength():
    """获取信号强度 (CSQ值: 0-31, 99=未知)"""
    try:
        csq = net.getCsq()
        return csq
    except:
        return -1


def get_signal_quality_text(csq):
    """将CSQ值转换为信号质量描述"""
    if csq < 0 or csq == 99:
        return "Unknown"
    elif csq < 10:
        return "Very Poor"  # 非常差
    elif csq < 15:
        return "Poor"  # 差
    elif csq < 20:
        return "Fair"  # 一般
    elif csq < 25:
        return "Good"  # 好
    else:
        return "Excellent"  # 优秀


def is_signal_weak():
    """检查信号是否弱 (CSQ < 15 认为是弱信号)"""
    csq = get_signal_strength()
    return csq >= 0 and csq < 15


def get_network_status():
    """获取网络状态"""
    try:
        return {
            "connected": _network_connected,
            "signal_strength": get_signal_strength(),
            "retry_count": _retry_count,
        }
    except Exception as e:
        print("[NETWORK] Get network status error: {}".format(e))
        return {"connected": False, "signal_strength": 0, "retry_count": _retry_count}


def register_recovery_callback(callback):
    """注册网络恢复回调函数"""
    global _recovery_callbacks
    if callback not in _recovery_callbacks:
        _recovery_callbacks.append(callback)
        print("[NETWORK] Recovery callback registered")


def _trigger_recovery_callbacks():
    """触发所有恢复回调"""
    global _recovery_callbacks
    for callback in _recovery_callbacks:
        try:
            callback()
        except Exception as e:
            print("[NETWORK] Recovery callback error: {}".format(e))


def get_connection_stats():
    """获取连接统计信息"""
    current_time = utime.time()

    if _network_connected:
        uptime = current_time - _last_connected_time if _last_connected_time > 0 else 0
        downtime = 0
    else:
        uptime = 0
        downtime = 0
        if _connection_lost_time > 0:
            downtime = current_time - _connection_lost_time
            # 防止时间异常导致负数
            if downtime < 0:
                downtime = 0

    csq = get_signal_strength()

    return {
        "connected": _network_connected,
        "uptime": uptime,
        "downtime": downtime,
        "retry_count": _retry_count,
        "signal_strength": csq,
        "signal_quality": get_signal_quality_text(csq),
        "weak_signal": is_signal_weak(),
    }


def force_reconnect():
    """强制重连网络"""
    global _retry_count

    print("[NETWORK] Force reconnecting...")

    # 先断开
    disconnect_network()
    utime.sleep(2)

    # 重置计数器
    _retry_count = 0

    # 重新连接
    return connect_network()


def is_long_disconnected(threshold_minutes=5):
    """检查是否长时间断网"""
    if _network_connected:
        return False

    if _connection_lost_time == 0:
        return False

    current_time = utime.time()
    disconnected_time = current_time - _connection_lost_time

    # 防止时间异常导致负数
    if disconnected_time < 0:
        print("[NETWORK] Time sync issue detected in disconnection check")
        return False

    return disconnected_time > (threshold_minutes * 60)


def test_network():
    """测试网络功能"""
    print("[NETWORK] Testing network functionality...")

    # 测试连接
    if connect_network():
        print("[NETWORK] Network connection test passed")

        # 显示网络状态
        status = get_network_status()
        print("[NETWORK] Network status: {}".format(status))

        # 显示连接统计
        stats = get_connection_stats()
        print("[NETWORK] Connection stats: {}".format(stats))

        # 断开连接
        disconnect_network()
    else:
        print("[NETWORK] Network connection test failed")

    print("[NETWORK] Network test completed")
